#ifndef RCOMPILER_COMMON_H
#define RCOMPILER_COMMON_H

#include "llvm/Pass.h"
#include <llvm/Module.h>
#include <llvm/Function.h>

extern "C" const char reactor_module_path[];

namespace R {
	class RCompiler;

	class RCompilerCommon {
		protected:
			static llvm::Function* makeIntrinsic(llvm::Function* func, bool accessMemory);
	public:
    llvm::Module*              selfModule;
//    llvm::Module*              rModule;

#define LLVM_STACK_FCT(name)\
		llvm::Function*	name##Push;\
		llvm::Function*	name##Pop;\
		llvm::Function*	name##Peek;\
		llvm::Function*	name##Set;\
		llvm::Function*	name##Size

    LLVM_STACK_FCT(any);
    LLVM_STACK_FCT(int);
    LLVM_STACK_FCT(call);

#undef LLVM_STACK_FCT

    llvm::Function* getEvaluator;
    llvm::Function* getStack;
    llvm::Function* JITPush;
    llvm::Function* JITPop;


		llvm::Function** evalFunctions;

		llvm::Function* loadFunctionAndCheck(const char* name, bool intrinsic = true, bool accessMemory = true);

		void patchMap();

		RCompilerCommon(llvm::Module* selfModule);
		virtual ~RCompilerCommon();
	};

	extern llvm::FunctionPass* createFunctionInlinerPass(RCompiler* compiler);
	extern llvm::FunctionPass* createStackToValuePass(RCompiler* compiler);
}

#endif
